﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using NAudio.Wave;
using Ursa.Controls;
using Whisper.net;

namespace STT_Test_Plus.ViewModels;

public partial class WhisperDemoViewModel:ObservableObject
{
    private WhisperFactory? whisperFactory = null;
    private CancellationTokenSource _tokenSource = null;
    public WhisperDemoViewModel()
    {
        RecordCmd = new RelayCommand(Start);

        this.SelectedWhisperModel = this.WhisperModels.FirstOrDefault();
    }

    private async void Start()
    {
        if (IsRecording)
        {
            //取消
            _tokenSource?.Cancel();
        }
        else
        {
            if (whisperFactory==null)
            {
                await MessageBox.ShowAsync("请选择模型", "错误", MessageBoxIcon.Error, MessageBoxButton.OK);
                return;
            }
            _tokenSource = new CancellationTokenSource();
            IsRecording = true;
            var recordResult = await MainWindowViewModel.Record(_tokenSource.Token);
            IsRecording = false;
            
            IsBusy = true;
            var speechToTextResult = await SpeechToText(recordResult,CancellationToken.None);
            IsBusy = false;
            this.RecordingText = speechToTextResult;
        }
    }
    
    /// <summary>
    /// 根据录音文件，将录音转换为文字
    /// </summary>
    /// <param name="fileName">录音文件名称</param>
    /// <param name="token">取消</param>
    /// <returns></returns>
    public  async Task<string> SpeechToText(string fileName,CancellationToken token)
    {
        using var processor = whisperFactory.CreateBuilder()
            .WithLanguage("auto")
            .Build();

        using var fileStream = File.OpenRead(fileName);

        StringBuilder stringBuilder = new StringBuilder();
        await foreach (var result in processor.ProcessAsync(fileStream,token))
        {
            stringBuilder.AppendLine(result.Text);
        }

        return stringBuilder.ToString();
    }
#pragma warning disable CA1822 // Mark members as static
    public string Greeting => "Welcome to Avalonia!";
#pragma warning restore CA1822 // Mark members as static

    /// <summary>
    /// 是否正在录音
    /// </summary>
    [ObservableProperty] private bool _isRecording;
    /// <summary>
    /// 录音翻译后的文本
    /// </summary>
    [ObservableProperty] private string? _recordingText;
    /// <summary>
    /// 是否正在忙碌
    /// </summary>
    [ObservableProperty] private bool _isBusy;

    [ObservableProperty] private string? _selectedWhisperModel;

    partial void OnSelectedWhisperModelChanged(string? value)
    {
        if (string.IsNullOrEmpty(value))
        {
            whisperFactory = null;
        }
        else
        {
            whisperFactory = WhisperFactory.FromPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,value));
        }
    }

    public RelayCommand RecordCmd { get; }

    public List<string> WhisperModels => Directory
        .GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.bin", SearchOption.TopDirectoryOnly)
        .Select(x => Path.GetFileName(x))
        .ToList();
}